﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.IO;
using System.Linq;
using System.Web.UI;
using AutoMapper;
using H2.NET.Business;
using H2.NET.Common;
using H2.NET.TaskRob;
using H2.NET.Web.Pages.SMD.Service;
using H2.NET.Web.Workflow.DwzCode;
using H2.NET.Web.Pages.SMD.Model;
using H2.NET.Data.Common;
using H2.NET.Web.Workflow.Helper;
using NPOI.SS.UserModel;

namespace H2.NET.Web.Pages.SMD
{
    public partial class BatchDepositChange : BasePage
    {
        public List<string> InOptions = new List<string>();
        public List<string> OutOptions = new List<string>();
        private string key;

        protected void Page_Load(object sender, EventArgs e)
        {

            if (!IsPostBack)
            {
                if (ReadOnly()) return;
                #region 表单是否占用

                if (IsOverFlow)
                {
                    btn_submit.Visible = false;
                    JsTip(string.Format("该表单正在被“{0}”处理，请稍后再试。", RobUser));
                    return;
                }

                #endregion

                DwzAssessment1.Category = "batch";

                #region “Fill in the form”、“Submit Document”步骤

                if (TaskAPI.Step == "Fill in the request" || TaskAPI.Step == "Submit Document")
                {
                    //如果退回就显示审批列表
                    if (!String.IsNullOrEmpty(TaskAPI.GetVariableBySingleValue("Changed")))
                    {
                        assessment.Visible = true;
                    }
                }
                #endregion

                #region 审核页面初始化

                else
                {

                    var storeMasterData = StoreMasterDataService.GetByTaskAPI(TaskAPI);
                    if (storeMasterData == null)
                    {
                        btn_submit.Visible = false;
                        JsTip("加载数据失败，请关闭页面重新打开！");
                        return;
                    }

                    hl_ExportPdf.NavigateUrl = "~/Tools/ExportPdf.ashx?taskid=" + TaskAPI.TaskID + "&filename=" + ".pdf";
                    hl_ExportPdf.Visible = true;
                    DepositUpload.Action = "deposit";
                }

                #endregion
            }
        }

        #region 只读表单

        private bool ReadOnly()
        {
            if (AksRequest.GetString("readonly") == "1")
            {
                OpenTasksInstance.OpenTasks.SetTaskClose(TaskAPI.Process, TaskAPI.Incident, TaskAPI.Step);
                assessment.Visible = true;
                btn_submit.Visible = false;
                DepositUpload.AllowDelete = false;
                DepositUpload.AllowUpload = false;
                DwzAssessment1.Visible = false;

                var storeMasterData = StoreMasterDataService.GetByTaskAPI(TaskAPI);
                if (storeMasterData == null)
                {
                    JsTip("该流程还没有提交过，没有任何数据！");
                    return true;
                }
                return true;
            }
            return false;
        }
        #endregion

        #region 方法 提交按钮、数据处理

        /// <summary>
        /// 数据处理方法
        /// </summary>
        /// <param name="returnMsg"></param>
        /// <returns></returns>
        private bool Send(ref string returnMsg)
        {
            var flag = false;
            try
            {

                #region 数据验证

                if (DepositUpload.attList.Count < 1 &&
                    (TaskAPI.Step == "Fill in the request" || TaskAPI.Step == "Submit Document"))
                {
                    returnMsg = "请上传保证金还款清单exel";
                    return false;
                }

                if (!DepositUpload.attList[DepositUpload.attList.Count - 1].FileName.Contains("保证金批量确认") &&
                    (TaskAPI.Step == "Finance Change"))
                {
                    returnMsg = "请上传保证金退还实际清单exel";
                    return false;
                }

                #endregion

                #region 引擎传值

                if (TaskAPI.Step == "Fill in the request" || TaskAPI.Step == "Submit Document")
                {
                    TaskAPI["ChangeType"] = "1";
                    TaskAPI.Summary = "财务审核/" + TaskHelper.getSummary(TaskAPI.Summary);
                }
                else if (TaskAPI.Step == "Finance Change")
                {
                    TaskAPI["Changed"] = DwzAssessment1.Assessment.Opinion;
                    if (DwzAssessment1.Assessment.Opinion == "1")
                        TaskAPI.Summary = "财务确认/" + TaskHelper.getSummary(TaskAPI.Summary);
                    else
                        TaskAPI.Summary = "(退回)填写设备保证金变更信息/" + TaskHelper.getSummary(TaskAPI.Summary);
                }

                #endregion

                #region 提交步骤

                Storage.TransactionExecute(o =>
                {
                    #region 审批意见记录

                    var ass = DwzAssessment1.Assessment;
                    var step = "";
                    var lastAss =
                        (t_Assessment.incident == TaskAPI.Incident & t_Assessment.process == TaskAPI.Process)
                            .ListFirst<t_Assessment>("time desc");
                    if ((lastAss != null && lastAss.Step != TaskAPI.Step) || lastAss == null)
                    {
                        Storage.Save(Storage.Context1, ass);
                    }
                    else
                    {
                        Logging.GetLogger().Info("=================表单已重复提交======================");
                        Logging.GetLogger().Info("TaskAPI.Step:" + TaskAPI.Step);
                        Logging.GetLogger().Info("TaskAPI.UserFullName:" + TaskAPI.UserFullName);
                        Logging.GetLogger().Info("时间：" + DateTime.Now);
                        Logging.GetLogger().Info("UserAPI.UserName:" + UserAPI.UserName);
                        Logging.GetLogger().Info("======================================================");
                        throw new Exception("该表单的步骤已经提交过了，请联系IT。");
                    }

                    #endregion

                    #region “Fill in the form”、“Submit Document”步骤

                    if (TaskAPI.IsBeginStep || TaskAPI.Step == "Submit Document")
                    {
                        var storeMasterData = new t_StoreMasterData
                        {
                            SubmitDate = DateTime.Now,
                            Creator = TaskAPI.UserName,
                            ApplicationNO = uc_head1.applicationNo,
                            DepositType = 1,
                            Process = TaskAPI.Process,
                            Incident = TaskAPI.Incident,
                            BusinessProcess = ass.BusinessProcess,
                            BusinessKey = ass.BusinessKey,
                        };

                        if (!TaskAPI.Summary.Contains("退回"))
                        {
                            BusinessService.SaveChildProcess(TaskAPI, ass, "active");
                            TaskAPI.Summary = "财务审核/" + TaskHelper.getSummary(TaskAPI.Summary) + "-" + DateTime.Now.Year +
                                              "年-" + ass.BusinessKey;
                            BusinessService.saveProcessRelation(TaskAPI, ass, null, null, null, null, null, null, null);
                        }

                        Storage.Save(Storage.Context1, storeMasterData);
                    }
                    else
                    {
                        if (DwzAssessment1.Assessment.Opinion == "1")
                        {
                            IWorkbook hssfworkbook;

                            var path = DepositUpload.attList[DepositUpload.attList.Count - 1].FilePath;
                            using (var fl = new FileStream(path, FileMode.Open, FileAccess.Read))
                            {
                                hssfworkbook = WorkbookFactory.Create(fl);
                            }
                            var sheet = hssfworkbook.GetSheetAt(0);
                            var rows = sheet.GetRowEnumerator();
                            var vdepostiBacth = (v_DepositBatchChange._AuthID != "").List<v_DepositBatchChange>();
                            var trans = new List<t_smd_DepositTran>();
                            var logs = new List<t_smd_StoreDataChangeLog>();
                            var deviceids = vdepostiBacth.Select(t => t.DeviceID).ToList().Distinct();

                            var oldDeposit =
                                (t_smd_Deposit._DeviceID != "" & t_smd_Deposit._DeviceID != null).List<t_smd_Deposit>(
                                    Storage.Context3);

                            var deposits = new List<t_smd_Deposit>();
                            while (rows.MoveNext())
                            {
                                var row = (IRow)rows.Current;
                                var index = row.RowNum;
                                var tran = new t_smd_DepositTran();
                                var log = new t_smd_StoreDataChangeLog();
                                var needSave = row.GetCell(14).ToString();
                                if (index == 0 || needSave != "yes")
                                {
                                    continue;
                                }

                                var fullsetsn = row.GetCell(10).ToString();
                                var issue = row.GetCell(19) == null ? "" : row.GetCell(19).ToString();
                                var sap = row.GetCell(20) == null ? "" : row.GetCell(20).ToString();
                                var returnAmout = row.GetCell(10).ToString();
                                var sellin = Utils.StrToInt(row.GetCell(16).ToString(), 0);
                                var sellnow = Utils.StrToInt(row.GetCell(17).ToString(), 0);

                                var vdeposit = vdepostiBacth.FirstOrDefault(t => t.FullSetSN == fullsetsn);
                                var error = "";
                                if (Utils.StrToInt(issue, 0) == 0)
                                {
                                    error = "请确保" + row.RowNum + 1 + "行返还金额填写正确。";
                                    throw new Exception(error);
                                }
                                if (sap == "")
                                {
                                    error = "请确保" + row.RowNum + 1 + "行SAP号填写正确。";
                                    throw new Exception(error);
                                }


                                tran.Amount = Utils.StrToInt(issue, 0);
                                tran.AssessmentID = ass.ID;
                                tran.AuthID = vdeposit.AuthID;
                                tran.DepositType = "返还";
                                tran.DeviceID = vdeposit.DeviceID;
                                tran.TranType = vdeposit.DealerCode;
                                tran.TranTime = DateTime.Now;
                                trans.Add(tran);

                                var deposit = oldDeposit.FirstOrDefault(t => t.DeviceID == vdeposit.DeviceID);
                                deposit.SapDeviceNo = sap;
                                deposit.StoreID = vdeposit.StoreID;
                                deposit.SellIn = sellin;
                                deposit.SellNow = sellnow;
                                deposit.Amount = (vdeposit.Amount - tran.Amount).Value;

                                log.AssessmentID = ass.ID;
                                log.DataID = vdeposit.DeviceID.ToString();
                                log.BeforeValue = vdeposit.Amount.ToString();
                                log.AfterValue = (vdeposit.Amount - tran.Amount).ToString();
                                log.Category = "BatchDepositChange";
                                log.ChangeTime = ass.Time;
                                log.FieldName = "DepositID";
                                logs.Add(log);

                                deposits.Add(deposit);
                            }

                            var logSql = "";
                            var tranSql = "";
                            var depositSql = "";

                            foreach (var log in logs)
                            {
                                logSql +=
                                    "Insert into t_smd_StoreDataChangeLog(Category,DataID,FieldName,BeforeValue,AfterValue,ChangeTime,UserID,AssessmentID) Values" +
                                    "('" + log.Category + "','" + log.DataID + "','" + log.FieldName + "','" +
                                    log.BeforeValue + "','" + log.AfterValue + "','" + log.ChangeTime + "','" +
                                    ass.UserFullName + "','" + log.AssessmentID + "');";
                            }
                            foreach (var tran in trans)
                            {
                                tranSql +=
                                    "Insert into t_smd_DepositTran(AuthID,DepositType,TranType,Amount,TranTime,AssessmentID,DeviceID) Values" +
                                    "('" + tran.AuthID + "','" + tran.DepositType + "','" + tran.TranType + "'," +
                                    tran.Amount + ",'" + tran.TranTime + "','" + tran.AssessmentID + "'," +
                                    tran.DeviceID + ");";
                            }
                            foreach (var deposit in deposits)
                            {
                                depositSql +=
                                    "Update t_smd_Deposit set Amount=" + deposit.Amount + ",SapDeviceNo='" +
                                    deposit.SapDeviceNo + "',SellIn=" + deposit.SellIn + ",SellNow=" + deposit.SellNow +
                                    " where DepositID=" + deposit.DepositID + ";";
                            }
                            var updatesql = logSql + tranSql + depositSql;
                            if (!string.IsNullOrEmpty(updatesql))
                            {
                                Storage.Context3.ExecuteScalar(new Command(logSql + tranSql + depositSql));
                            }

                            step = "finish";
                        }
                    }


                    #endregion

                    flag = TaskAPI.Send();

                    if (TaskAPI.StepStatus("Finish") == 1 || step == "finish")
                    {
                        BusinessService.SaveChildProcess(TaskAPI, DwzAssessment1.Assessment, "Finish");
                    }

                    if (!flag) o.Rollback();

                    #region 关联 实例号

                    if (TaskAPI.IsInitiate || TaskAPI.Step == "Submit Document")
                    {
                        (t_StoreMasterData._Process == TaskAPI.Process & t_StoreMasterData._Incident == 0).Edit<t_StoreMasterData>(p =>
                        {
                            p.Incident = TaskAPI.Incident;
                        });

                        (t_Assessment.process == TaskAPI.Process & t_Assessment.incident == 0 & t_Assessment.assignedToUserName == UserAPI.UserName).Edit<t_Assessment>(p =>
                        {
                            p.Incident = TaskAPI.Incident;
                        });

                        (t_Attachment.process == TaskAPI.Process & t_Attachment.incident == 0 & t_Attachment.username == UserAPI.UserName).Edit<t_Attachment>(p =>
                        {
                            p.Incident = TaskAPI.Incident;
                        });
                    }

                    #endregion

                    #region 自动跳转到财务审核

                    if (!TaskAPI.IsBeginStep) return;
                    System.Threading.Thread.Sleep(2000);
                    var task = TaskHelper.GetTask(TaskAPI.Process, TaskAPI.Incident, "Submit Document");

                    while (task == null)
                    {
                        task = TaskHelper.GetTask(TaskAPI.Process, TaskAPI.Incident, "Submit Document");
                        System.Threading.Thread.Sleep(1000);
                    }
                    var taskapi = new TaskAPI();
                    taskapi.Load(task.strTaskId);
                    taskapi.Send();


                    #endregion
                }
            );
                #endregion
            }
            catch (Exception ex)
            {
                returnMsg = ex.Message.Replace("\"", "\\\"");
                Logging.GetLogger().Error("调用DepositChange.aspx方法Send_Click出错：" + ex);
                flag = false;
            }

            return flag;
        }

        /// <summary>
        /// 提交按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btn_submit_Click(object sender, EventArgs e)
        {
            var returnMsg = string.Empty;
            if (Send(ref returnMsg))
            {
                btn_submit.Visible = false;
                ScriptManager.RegisterStartupScript(this, GetType(), "info_prompt", "$.jBox.prompt('操作成功！','提示', 'info', { closed: function () { window.opener.reload(); closeWin(); } });", true);
            }
            else
            {
                returnMsg = string.IsNullOrEmpty(returnMsg) ? Resources.Global.C_00_Failed : returnMsg;
                ScriptManager.RegisterStartupScript(this, GetType(), "info_tip", "$.jBox.prompt('" + returnMsg + "','提示', 'info');", true);
            }
        }

        /// <summary>
        /// 转移保证金变更日志，并且更新保证金
        /// </summary>
        private void SaveDepositTrans(t_Assessment ass)
        {
            var assessments = AssessmentService.FindByPI(TaskAPI.Process, TaskAPI.Incident);
            var depositTrans = DepositTranService.FindInAssIds(assessments.Select(t => t.ID).ToList());

            Mapper.CreateMap<t_StoreDepositTran, t_smd_DepositTran>();
            var list = Mapper.Map<List<t_StoreDepositTran>, List<t_smd_DepositTran>>(depositTrans);

            foreach (t_smd_DepositTran storeDepositTran in list)
            {
                storeDepositTran.EntityState._FieldState.Remove("DepositTranID");
            }

            // 最后一起保存
            // ReSharper disable once CoVariantArrayConversion
            // Storage.Save(Storage.Context3, list.ToArray());

            // 根据 设备id、门店id 区分每条变更的记录
            var items = list.GroupBy(t => new { t.DeviceID, t.StoreID });
            var deposits = new List<t_smd_Deposit>();
            var changeLogs = new List<t_smd_StoreDataChangeLog>();
            var deleteDepositIds = new List<int>();
            foreach (var item in items)
            {
                //deleteDepositId.Add()

                var autoBusinessKey = TaskAPI.GetVariableBySingleValue("AutoBusinessKey");

                var gKey = item.Key;
                var gDepositTrans = item.ToList();

                var lOut = gDepositTrans.Where(t => t.DepositType == "退款").Sum(t => t.Amount).Value;
                if (key == Constant.PROCESS_CHANGEOTHER)
                {
                    lOut = gDepositTrans.Where(t => t.DepositType == "返还").Sum(t => t.Amount).Value;
                }
                var lIn = gDepositTrans.Where(t => t.DepositType == "进款").Sum(t => t.Amount).Value;

                var deposit = DepositService.GetDeviceDeposit(gKey.StoreID, gKey.DeviceID.Value);

                if (deposit == null)
                {
                    var store = StoreService.GetSmdStoreById(gKey.StoreID);

                    deposit = new t_smd_Deposit
                    {
                        StoreID = gKey.StoreID,
                        DeviceID = gKey.DeviceID.Value,
                        AuthID = store.AuthID,
                        DepositType = "设备保证金",
                        PostingDate = DateTime.Now
                    };

                    // 如果是新纪录，把以前的保证金删掉
                    var deviceDeposits =
                        (t_smd_Deposit._DeviceID == deposit.DeviceID & t_smd_Deposit._DepositType == "设备保证金")
                            .List<t_smd_Deposit>(Storage.Context3);
                    deleteDepositIds.AddRange(deviceDeposits.Select(t => t.DepositID).ToList());
                }

                deposit.Amount = deposit.Amount + (lIn - lOut);

                // 如果是经销商变更、设备三方转移，就直接覆盖
                if (autoBusinessKey == Constant.PROCESS_CHANGEDEALER || autoBusinessKey == Constant.PROCESS_TRANSFER)
                {
                    deposit.Amount = lIn;
                }

                deposits.Add(deposit);

                var deviceDeposit = (v_DeviceDeposit._DeviceID == deposit.DeviceID).ListFirst<v_DeviceDeposit>(Storage.Context3, " DepositID desc");
                var changeLog = new t_smd_StoreDataChangeLog();
                changeLog.Category = "DepositChange";
                changeLog.DataID = deposit.DeviceID.ToString();
                changeLog.FieldName = "Amount";
                changeLog.BeforeValue = (deviceDeposit == null ? 0 : deviceDeposit.Amount).ToNullSafeString();
                changeLog.AfterValue = deposit.Amount.ToString();
                changeLog.ChangeTime = DateTime.Now;
                changeLog.UserID = ass.AssignedToUserFullName;
                changeLog.AssessmentID = ass.ID;
                changeLogs.Add(changeLog);

            }

            Storage.Save(Storage.Context3, changeLogs.ToArray());
            Storage.Save(Storage.Context3, list.ToArray());
            Storage.Save(Storage.Context3, deposits.ToArray());

            // 清楚设备保证金冗余数据
            if (deleteDepositIds.Count > 0)
            {
                t_smd_Deposit._DepositID.In(deleteDepositIds).Delete<t_smd_Deposit>(Storage.Context3);
            }
        }

        #endregion

    }
}